package cn.anecansaitin.whimsy.common.extension.comboSystem.skills.rockSceptre;

import cn.anecansaitin.whimsy.common.entity.WeaponSwingCollision;
import cn.anecansaitin.whimsy.common.extension.comboSystem.ExtraData;
import cn.anecansaitin.whimsy.common.extension.comboSystem.INormalSkill;
import cn.anecansaitin.whimsy.common.item.RockSceptre;
import cn.anecansaitin.whimsy.util.MathUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.phys.Vec3;
import software.bernie.geckolib.animatable.GeoItem;

import java.util.HashSet;
import java.util.List;

public class Attack5 implements INormalSkill {
    @Override
    public int precastTick() {
        return 8;
    }

    @Override
    public int activeTick() {
        return 1;
    }

    @Override
    public int backswingTick() {
        return 10;
    }

    @Override
    public void prePrecast(Player player, ExtraData extra) {
        if (!player.level().isClientSide) {
            extra.getData("itemStack", ItemStack.class).ifPresent((i) -> {
                RockSceptre item = (RockSceptre) i.getItem();
                item.triggerAnim(player, GeoItem.getOrAssignId(i, (ServerLevel) player.level()), "con", "attack5.precast");
                item.triggerAnim(player, GeoItem.getOrAssignId(i, (ServerLevel) player.level()), "stone", "idle");
            });
        }
    }

    @Override
    public void precast(int skillTick, Player player, ExtraData extra) {

    }

    @Override
    public void preActive(Player player, ExtraData extra) {
        if (!player.level().isClientSide) {
            extra.getData("itemStack", ItemStack.class).ifPresent((i) -> {
                RockSceptre item = (RockSceptre) i.getItem();
                item.triggerAnim(player, GeoItem.getOrAssignId(i, (ServerLevel) player.level()), "con", "attack5.active");
            });
        }
    }

    @Override
    public void active(int skillTick, Player player, ExtraData extra) {
        if (!player.onGround()) {
            return;
        }

        WeaponSwingCollision[] collisions = WeaponSwingCollision.lowFlyingSectorRange(player, 4, 180f, 11, 3f, new HashSet<>(), (entity) -> {
            if (entity instanceof LivingEntity living) {
                living.knockback(0.8, Mth.sin(player.getYRot() * ((float) Math.PI / 180F)), (-Mth.cos(player.getYRot() * ((float) Math.PI / 180F))));
            }
        });

        List<Vec3> vec31 = MathUtil.distributePointsOnTriangle(collisions[0].position(), collisions[0].getFinalPos(), collisions[collisions.length / 2].getFinalPos(), 10);
        List<Vec3> vec32 = MathUtil.distributePointsOnTriangle(collisions[0].position(), collisions[collisions.length - 1].getFinalPos(), collisions[collisions.length / 2].getFinalPos(), 10);

        if (player.level() instanceof ServerLevel level) {
            for (Vec3 vec3 : vec31) {
                level.sendParticles(new BlockParticleOption(ParticleTypes.BLOCK, level.getBlockState(new BlockPos((int) vec3.x, (int) vec3.y - 1, (int) vec3.z))), vec3.x, vec3.y, vec3.z, 10, 0, 0, 0, 0.15f);
            }

            for (Vec3 vec3 : vec32) {
                level.sendParticles(new BlockParticleOption(ParticleTypes.BLOCK, level.getBlockState(new BlockPos((int) vec3.x, (int) vec3.y - 1, (int) vec3.z))), vec3.x, vec3.y, vec3.z, 10, 0, 0, 0, 0.15f);
            }
        }

        player.level().playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BONE_BLOCK_BREAK, player.getSoundSource(), 1.5F, 0.5F);
    }

    @Override
    public void preBackswing(Player player, ExtraData extra) {
        if (!player.level().isClientSide) {
            extra.getData("itemStack", ItemStack.class).ifPresent((i) -> {
                RockSceptre item = (RockSceptre) i.getItem();
                item.triggerAnim(player, GeoItem.getOrAssignId(i, (ServerLevel) player.level()), "stone", "earthquake");
            });
        }
    }

    @Override
    public void backswing(int skillTick, Player player, ExtraData extra) {

    }

    @Override
    public void finish(Player player, ExtraData extra) {
        if (!player.level().isClientSide) {
            extra.getData("itemStack", ItemStack.class).ifPresent((i) -> {
                RockSceptre item = (RockSceptre) i.getItem();
                item.triggerAnim(player, GeoItem.getOrAssignId(i, (ServerLevel) player.level()), "con", "idle");
                item.triggerAnim(player, GeoItem.getOrAssignId(i, (ServerLevel) player.level()), "stone", "idle");
            });
        }
    }

    @Override
    public boolean canCachingKey(int skillTick, ExtraData extra) {
        return skillTick >= 8 && skillTick <= 19;
    }

    @Override
    public boolean canDeriving(int skillTick, ExtraData extra) {
        return skillTick >= 11 && skillTick <= 19;
    }

    @Override
    public String getName() {
        return "attack5";
    }
}
